import 'package:fluro/fluro.dart';
import 'package:flutter/widgets.dart';
import 'package:imperius_insights/routes/paths.dart';
import 'package:provider/provider.dart';

import 'service/api_healthcheck.dart';
import 'service/measure.dart';
import 'service/overt.dart';
import 'typings.dart';

typedef OnRequestMeasured = void Function(MeasurementRequest request, MeasurementResult result);
typedef OnApiHealthChecked = void Function(HealthCheckRequest request, HealthCheckResult result);
typedef OnNetworkInfoResolved = dynamic Function(NetworkInfo networkInfo);
typedef OnConnectivityInfoResolved = dynamic Function(ConnectivityInfo connectivityInfo);

///
/// 网络连通性诊断
/// · 网络是否开启
/// · 是否联网（dns ip，baidu）
/// · 网速侦测
/// · 服务是否可连通
/// 服务诊断
/// · 各个API是否正常
/// 网络信息收集
class Service {
  static navigateToDiagnostic(BuildContext context) {
    final router = Provider.of<Router>(context, listen: false);
    router.navigateTo(context, Paths.diagnostic,
        transition: TransitionType.cupertino);
  }

  ///
  /// 查询设备网络信息
//  Future<NetworkInfo> queryNetworkInfo() async {
//    final connResult = await Connectivity().checkConnectivity();
//    if (connResult == ConnectivityResult.none) {
//      return null;
//    }
//    if (connResult == ConnectivityResult.mobile) {
//      return NetworkInfo(NetworkType.MOBILE);
//    }
//    if (connResult == ConnectivityResult.wifi) {
//      final ssid = await Connectivity().getWifiBSSID();
//      final ip = await Connectivity().getWifiIP();
//      final wifiName = await Connectivity().getWifiName();
//      return WifiNetworkInfo(NetworkType.WIFI,
//          ssid: ssid, innerIp: ip, name: wifiName);
//    }
//    return NetworkInfo(NetworkType.Unknown);
//  }

  Future<ConnectivityInfo> resolveConnectivityInfo() async {
//    final networkInfo = await queryNetworkInfo();
    final overt = await getOvert();
    return ConnectivityInfo(
//        networkInfo: networkInfo,
        networkInfo: NetworkInfo(NetworkType.Unknown),
        overtIp: overt != null ? overt.ip : null,
        localDns: overt != null ? overt.localDns : null,
        available: overt != null ? (overt.ip != null) : false);
  }

  Future<PerformanceSummary> measureNetworkPerformance(
      List<MeasurementRequest> measureRequests, OnRequestMeasured onRequestMeasured) async {
    final connectivityInfo = await this.resolveConnectivityInfo();
    final measurements = List<MeasurementResult>();
    for (MeasurementRequest mr in measureRequests) {
      final measureResult = await measure(mr);
      measurements.add(measureResult);
      onRequestMeasured(mr, measureResult);
    }
    return PerformanceSummary(
        connectivityInfo: connectivityInfo, measurements: measurements);
  }

  Future<HealthCheckSummary> healthCheckApis(
      List<HealthCheckRequest> healthCheckRequests, OnApiHealthChecked onApiHealthChecked) async {
    final connectivityInfo = await this.resolveConnectivityInfo();
    final healthCheckResults = List<HealthCheckResult>();
    for (HealthCheckRequest hcr in healthCheckRequests) {
      final healthCheckResult = await healthCheck(hcr);
      healthCheckResults.add(healthCheckResult);
      onApiHealthChecked(hcr, healthCheckResult);
    }
    return HealthCheckSummary(
        connectivityInfo: connectivityInfo, healthCheckResults: healthCheckResults);
  }
}
